Completed
Push — master ( 77d906...cc193b )
by Jean
01:28
created

configure.js ➔ ... ➔ ???   C

Complexity

Conditions 13
Paths 10

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
c 1
b 0
f 0
nc 10
nop 2
dl 0
loc 41
rs 5.1234

How to fix   Complexity   

Complexity

Complex classes like configure.js ➔ ... ➔ ??? often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * @file Module 'configure'
3
 * @author woshilapin <[email protected]>
4
 * @version 0.3.0
5
 */
6
/**
7
 * Manage global configuration for Codingame's connector
8
 * @module configure
9
 */
10
import fs from 'fs';
11
import readline from 'readline';
12
import subprocess from 'child_process';
13
14
let parameters = {};
15
16
const rl = readline.createInterface({
17
	"input": process.stdin,
18
	"output": process.stdout
19
});
20
21
22
/**
23
 * Load the configuration file
24
 *
25
 * @name load
26
 * @function
27
 * @param {string} path Path of the configuration file
28
 * @param {Object} [options] Additionnal parameters which will replace parameters from configuration file
0 ignored issues
show
Documentation Bug introduced by
The parameter [options] does not exist. Did you maybe mean options instead?
Loading history...
29
 * @returns {Promise<Object>} Configuration parameters
30
 * @memberof module:configure
31
 * @instance
32
 */
33
let load = function load(path, options) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable load already seems to be declared on line 33. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
34
	return new Promise(function(resolve, reject) {
35
		let resolvefromerror = function resolvefromerror(error) {
36
			if (options !== undefined && typeof options === `object`) {
37
				Object.assign(parameters, options);
38
				resolve(options);
39
			} else {
40
				reject(error);
41
			}
42
		};
43
		try {
44
			fs.readFile(path, `utf8`, function(error, file) {
45
				if (error) {
46
					resolvefromerror(error);
47
				} else {
48
					try {
49
						parameters = JSON.parse(file);
50
					} catch (error) {
51
						reject(error);
52
					}
53
					Object.assign(parameters, options);
54
					resolve(parameters);
55
				}
56
			});
57
		} catch (error) {
58
			resolvefromerror(error);
59
		}
60
	});
61
};
62
63
/**
64
 * Get the value from configuration
65
 *
66
 * @name get
67
 * @function
68
 * @param {string} name Name of the parameter
69
 * @param {string} [option] 'shell' if value may be executed as shell command, 'file' if value is a path and content of file should be returned
0 ignored issues
show
Documentation Bug introduced by
The parameter [option] does not exist. Did you maybe mean option instead?
Loading history...
70
 * @param {string} [question] If present and value not found, will be shown to the user to ask for the value on 'stdin'
0 ignored issues
show
Documentation Bug introduced by
The parameter [question] does not exist. Did you maybe mean question instead?
Loading history...
71
 * @returns {Promise<string|Array|Object>} The value of the parameter
72
 * @memberof module:configure
73
 * @instance
74
 */
75
let get = function get(name, option, question) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable get already seems to be declared on line 75. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
76
	return new Promise(function(resolve, reject) {
77
		if (!name || typeof name !== `string`) {
78
			reject(new Error(`'configure.get()' takes at least one string parameter.`));
79
		}
80
		let property = parameters[name];
81
		if (property !== undefined && option !== undefined && option === `shell` && Array.isArray(property)) {
82
			subprocess.exec(property.join(` `), function(error, stdout, stderr) {
83
				if (error) {
84
					console.error(stderr);
85
					reject(error);
86
				} else {
87
					let result = stdout.trim();
88
					parameters[name] = result;
89
					resolve(result);
90
				}
91
			});
92
		} else if (property !== undefined && option !== undefined && option === `file`) {
93
			fs.readFile(property, `utf8`, function(error, file) {
94
				if (error) {
95
					reject(error);
96
				} else {
97
					resolve({
98
						"path": property,
99
						"data": file
100
					});
101
				}
102
			});
103
		} else if (property !== undefined) {
104
			resolve(property);
105
		} else {
106
			if (question !== undefined && typeof question === `string`) {
107
				rl.question(question, (result) => {
108
					throw new Error('aaaahahhahah')
109
					parameters[name] = result;
0 ignored issues
show
Bug introduced by
The variable result seems to be never initialized.
Loading history...
introduced by
This code is unreachable and can thus be removed without consequences.
Loading history...
110
					resolve(result);
0 ignored issues
show
introduced by
This code is unreachable and can thus be removed without consequences.
Loading history...
111
				});
112
			} else {
113
				reject(new Error(`'configure.get()' second parameter must be a string.`));
114
			}
115
		}
116
	});
117
};
118
119
/**
120
 * Ask configure module to delete a parameter
121
 *
122
 * @name forget
123
 * @function
124
 * @param {string} name Name of the parameter
125
 * @memberof module:configure
126
 * @instance
127
 */
128
let forget = function forget(name) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable forget already seems to be declared on line 128. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
129
	if (typeof name !== `string`) {
130
		throw new Error(`'configure.forget()' function takes one string parameter.`);
131
	} else {
132
		delete parameters[name];
133
	}
134
};
135
136
export default {
137
	"load": load,
138
	"get": get,
139
	"forget": forget
140
};
141